<template>
    <div class="ComposeMaterial">
        <a-upload
            :disabled="loading"
            v-model:file-list="fileList"
            :max-count="10"
            :customRequest="customRequest"
            :before-upload="beforeUpload"
            :multiple="true"
            :showUploadList="false"
            name="file"
            :directory="directory"
            accept=".mp4,.mov,.3gp"
        >
        <slot name="content">
          <a-button type="primary" ghost>
              <plus-outlined />
              本地上传
          </a-button>
        </slot>
        </a-upload>
    </div>
  </template>
  
  <script setup>
  import {
    reactive,
    onMounted,
    onUnmounted,
    watch,
    ref,
    nextTick,
    createVNode,
    defineProps,
    defineEmits
  } from "vue";
  import request from "@/common/utils/request";
  import { computed } from "vue";
  import { useRouter } from "vue-router";
  import axios from "axios"; 

  const router = useRouter();
  
  import {ExclamationCircleOutlined,PlusOutlined} from "@ant-design/icons-vue";
  
  import defaultSetting from "@/common/utils/defaultSetting.js";
  
  import { message, Modal, Empty, notification } from "ant-design-vue";
  import store from "@/store/index.js";
  import { upload } from "@/common/utils/uploader/index";
  import utils from'@/common/utils/utils.js'
  
  // 充值弹窗
  const vipVisible = ref(false);
  
  const props = defineProps({
  });

const emit = defineEmits(["success","loadingUpload", 'getMediaList:arr']);
  
  const kuarongRef = ref(null);
  
  const state = reactive({});

  // 上传完成后的素材id
  const mediaList = ref([])
  
  
  const work_ai_config = computed(() => {
    return store?.state?.shotstack?.work_ai_config || {};
  });
  
  const isAlionline = computed(() => {
    return work_ai_config.value?.shotstack_driver == "alionline";
  });
  
  const isOss = computed(() => {
    return work_ai_config.value?.upload_driver == "oss";
  });
  

  // 默认返回成片第一个成片项目
  const isSelectId = computed({
    get() {
      return typeof state.selectId == "number"
        ? state.selectId
        : state.itemList?.[0]?.id || "";
    },
    set(data) {
      state.selectId = data;
    },
  });
  
  // 获取成片列表
  const successUpload = async () => {
    emit('success')
  };
  const optionsDetail = ref([]);
  const initUpdateb = async () => {
    let params = {
      merchant_library_id: isSelectId.value,
      folder_type: "video",
    };
    const res = await request.get(
      "/work_ai",
      "/user/shotstack/folder/select/list",
      params
    );
    optionsDetail.value = res.result;
  };
  
  const now_KEY = ref("");
  const newvisible = ref(false);
  const choose = ref("");
  const now_e = ref("");
  const BASE_URL = ref("");
  const all_file_list = ref([]);
  const fileList = ref([]);
  const iscount = ref(0);
  const queryData = ref({
    files: [],
  });
  const updatevideo = ref([]);
  
  // 上传前的准备
  const beforeUpload = async (file, fileList) => {
    // all_file_list.value = fileList
    
    all_file_list.value.push(fileList);
    return new Promise((resolve) => {
      const isLt1G = file.size / 1024 / 1024 / 1024 < 1;
      if (!isLt1G) {
        message.error("视频文件不可大于 1GB!");
        resolve(false);
        return;
      }
      const video = document.createElement("video");
      const blobURL = URL.createObjectURL(file);
      video.src = blobURL;
      video.onloadedmetadata = () => {
        const duration = video.duration;
        const width = video.videoWidth;
        const height = video.videoHeight;
  
        if (duration > 3600) {
          message.error("视频文件不能大于 60 分钟时长!");
          resolve(false);
          return;
        }
  
        if (width > 4096 || height > 4096) {
          message.error("视频最大不能超过 4096px!");
          resolve(false);
          return;
        }
  
        resolve(true);
      };
    });
  };
  
  const consumes = ref("");
  const unit = ref("");
  const unit_name = ref("");
  const getnewRule = async (count) => {
    const res = await request.get(
      "/work_ai",
      "/user/shotstack/point/release/get",
      { number: count }
    );
    consumes.value = res.pointInfo.consumes;
    unit.value = res.pointInfo.unit;
    unit_name.value = res.pointInfo.name;
  };
  
  // 上传组件  手动上传
  const customRequest = async(file) => {
    queryData.value.files.push(file.file);
  
    const url = URL.createObjectURL(file.file);
    updatevideo.value.push({
      url: url,
      name: file.file.name,
      id: file.file.uid,
      isplayshow: true,
      up_ing: false,
      up_finish: false,
    });
  
    iscount.value += 1;
    if (iscount.value != all_file_list.value.length) return;
    await getnewRule(all_file_list.value.length);
  
    Modal.confirm({
      title: "提示",
      icon: createVNode(ExclamationCircleOutlined),
      content: `已添加${updatevideo.value.length}个成片, 预计将消耗${consumes.value}${unit.value}${unit_name.value}, 你确定继续吗?`,
      cancelText: "取消",
      okText: "确定",
      onOk: async () => {
        saveFn();
      },
      onCancel() {
        clearFn();
      },
    });
  };
  
  
  const clearFn = () => {
    updatevideo.value = [];
    all_file_list.value = []
    iscount.value = 0
  };
  
  const loading = ref(false);
  const isAll_upload = ref(false);
  const isUploadComplete = ref(false);
  const failed_btn = ref(false);
  const isupdate = ref(false);
  const noenzu = ref(false);
  const SetUploadPath = ref("");
  const fileMaxSize = ref("");
  const free_send_text = ref("");
  const fileMaxSizeErr = ref("");
  const ALLshouldContinuePolling = ref(true);
  
  // 保存 上传按钮
  const saveFn = async () => {
    await initUpdateb();
    loading.value = true;
    //-----------------------------------cos上传----------------------------------
  
    BASE_URL.value = defaultSetting.requestDomain;
    if (process.env.NODE_ENV === "development") {
      BASE_URL.value = BASE_URL.value + "/api";
    }
    ALLshouldContinuePolling.value = true;
    const uploadQueue = [];
    const MAX_CONCURRENT_UPLOADS = 3;
  
    // 检查剩余空间并上传文件
    async function checkSpaceAndUpload(file, index) {
      try {
        // 每次上传前检查剩余空间
        const res = await request.post("/work_ai", "/material/get/capacity");
        const remainingCapacity = parseInt(res.result.remainingCapacity, 10);

        if (remainingCapacity < file.size) {
          // 内存不够
          message.error(`存储空间不足，无法上传文件：${file.name}`);
          return;
        }
        const formData = new FormData();
        formData.append("file", file);
        formData.append("type", "video");
        formData.append("scene", "video");
        formData.append(
          "merchant_folder_statck_id",
          optionsDetail.value[0].id
        );
        formData.append("org_id", utils.getOrgId());
        formData.append("user_token", utils.getToken());
        formData.append(
          "cur_env",
          utils.isMobile() ? "h5" : import.meta.env.ELECTRON ? "desktop" : "pc"
        );
        formData.append("team_id", utils.getCurrentTeam());
        formData.append("upload_from", "film");
  
        const response = await axios({
          method: "post",
          url: `${BASE_URL.value}/work_ai/material/upload`,
          data: formData,
          headers: {
            "Content-Type": "multipart/form-data",
            "Org-Token": utils.getToken(),
          },
        });
  
        if (response?.data?.data?.errorData.length > 0) {
          // 错误处理
          notification.warn({
            message: response.data.data.errorData[0],
            duration: 2,
          });
          loading.value = false;
          updatevideo.value = [];
          queryData.value.files = [];
          return;
        }
  
        // 上传中状态
        updatevideo.value[index].up_ing = true;
        let pollInterval; // 用于存储setInterval的返回值，以便稍后清除
        let shouldContinuePolling = true;
  
        // 在上传响应后开始轮询
        const startPolling = () => {
          pollInterval = setInterval(async () => {
            if (!ALLshouldContinuePolling.value) {
              clearInterval(pollInterval); // 如果应停止轮询，则清除定时器
              loading.value = false;
              return;
            }
            if (!shouldContinuePolling) {
              clearInterval(pollInterval); // 如果应停止轮询，则清除定时器
              loading.value = false;
              return;
            }
  
            try {
              const res = await request.get(
                "/work_ai",
                "/material/upload/status",
                { taskId: response.data.data.returnData[0].taskId }
              );
              if (res.status === 1) {
                // 继续轮询
              } else if (res.status === 2) {
                shouldContinuePolling = false; // 设置标志以停止轮询
                clearInterval(pollInterval); // 清除定时器
  
                updatevideo.value[index].up_ing = false;
                updatevideo.value[index].up_finish = true;
                const allVideosFinished = updatevideo.value.every(
                  (item) => item.up_finish === true
                );
                if (allVideosFinished) {
                  console.log(updatevideo.value,'全部上传完成??');
                  
                  // 全部上传成功
                  loading.value = false;
                   successUpload();
                }
              } else if (res.status === 3) {
                // 上传失败  停止轮训
                shouldContinuePolling = false; // 设置标志以停止轮询
                clearInterval(pollInterval); // 清除定时器
                loading.value = false;
                updatevideo.value[index].up_ing = false;
              }
            } catch (error) {
              clearInterval(pollInterval);
              loading.value = false;
               successUpload();
            }
          }, 2000);
        };
  
        startPolling();
      } catch (error) {
        console.error("Error during upload:", error);
      }
    }
  
    // cos上传
    async function startUploads() {
      for (let i = 0; i < queryData.value.files.length; i++) {
        const file = queryData.value.files[i];
        // 将上传任务添加到队列中
        uploadQueue.push(checkSpaceAndUpload(file, i));
  
        // 如果队列中的任务数量超过了最大并发数，等待队列中的一个任务完成
        if (uploadQueue.length > MAX_CONCURRENT_UPLOADS) {
          await uploadQueue.shift();
        }
      }
  
      // 等待所有上传任务完成
      await Promise.all(uploadQueue);
    }
  
    //----------------------------------- oss上传 -------------------------------
  
    async function processQueue(queue, concurrency) {
      const runningTasks = new Set();
      const results = [];
  
      const addTask = async () => {
        if (queue.length === 0) {
          return;
        }
  
        const task = queue.shift();
        const promise = task()
          .then((res) => {
            results.push(res);
            runningTasks.delete(promise);
            addTask();
          })
          .catch((error) => {
            results.push(null);
            runningTasks.delete(promise);
            addTask();
          });
  
        runningTasks.add(promise);
      };
  
      for (let i = 0; i < concurrency; i++) {
        addTask();
      }
  
      while (runningTasks.size > 0 || queue.length > 0) {
        await Promise.race(runningTasks);
      }
  
      return results;
    }
    let oss_config;
    async function getOss_config() {
      const response = await request.post(
        "/work_ai",
        "/upload/oss/config/ststoken"
      );
      if (response.sts) {
        oss_config = response.sts;
      } else {
        const Reres = await request.post(
          "/work_ai",
          "/upload/oss/config/ststoken",
          {
            isRefresh: "1",
          }
        );
        oss_config = Reres.sts;
      }
    }
  
    async function startOssUploads() {
      await getOss_config();
  
      let upDataList = queryData.value.files.map((item) => ({
        ...item,
        name: item.name,
        id: item.uid,
        state: 0,
        percent: 0,
        iscancel: false,
      }));
  
      // 将上传数据 同步至vuex
      store.dispatch("SetUpDateList", upDataList);
  
      const uploadQueue = queryData.value.files.map((file, i) => async () => {
        updatevideo.value[i].up_ing = true;
  
        const config = {
          SetUploadPath: SetUploadPath.value,
          oss_config: oss_config,
        };
  
        const res = await upload(file, config);
  
        if (res.state == false) {
          updatevideo.value.forEach((v1) => {
            if (v1.name == res.name) {
              v1.up_ing = false;
              v1.up_finish = true;
              v1.isfailed = true;
            }
          });
          if (updatevideo.value.every((item) => item.up_finish == true)) {
            isAll_upload.value = true;
          }
        }
  
        if (res.fileUrl) {
          let up_paramas = {
            merchant_folder_statck_id: optionsDetail.value[0].id,
            material_type: "video",
            material_name: res.name,
            material_url: res.fileUrl,
            group_id: isSelectId.value,
            material_path: "",
            material_size: file.size,
            material_duration: "",
            width: "",
            height: "",
            oss_media_id: "",
            cover_url: "",
            oss_cover_media_id: "",
            upload_from: "film",
            material_exif: "",
          };
  
          return request
            .post("/work_ai", "/user/mobile/media", up_paramas)
            .then((res) => {
              console.log(res,'上传完成后的结果');
              
              updatevideo.value.forEach((v1) => {
                if (v1.name == file.name) {
                  v1.up_ing = false;
                  v1.up_finish = true;
                }
              });
  
              if (updatevideo.value.every((item) => item.up_finish == true)) {
                isAll_upload.value = true;
              }

              // 存放上传完成后的结果
              mediaList.value.push(res?.result)

              return res;
            })
            .catch((error) => {
              return null;
            });
        }
      });
  
      const results = await processQueue(uploadQueue, 2);
  
      if (results.every((res) => res?.result) && isAll_upload.value) {
        isUploadComplete.value = true;
        updatevideo.value = [];
        isupdate.value = false;
        queryData.value.files = [];
        message.success("上传完成!");
        clearFn()
        loading.value = false;
        store.dispatch("SetUpDateList", []);
      }
  
      if (isAll_upload.value && results) {
        isUploadComplete.value = true;
        updatevideo.value = [];
        isupdate.value = false;
        queryData.value.files = [];
        loading.value = false;
        store.dispatch("SetUpDateList", []);
      }
    }
  
    
    if (isAlionline.value || isOss.value) {
      // oss
      startOssUploads();
    } else {
      // cos
      startUploads().catch(console.error);
    }
  
    
  };
  
  // 视频数组
  watch(
    () => updatevideo.value,
    (val) => {
      if (val.every((item) => !item.up_ing)) {
        // 全部执行完成
        loading.value = false;
        if (val.some((item) => item.isfailed)) {
          // 重新上传标识
          failed_btn.value = true;
        }
      }
  
      if (val.every((item) => item.up_finish == true) && !isUploadComplete) {
        isUploadComplete.value == true;
      }
    },
    {
      deep: true,
    }
  );

  watch(
    ()=>loading.value,
    (val)=>{
      emit('loadingUpload', val)
      console.log(val, 'watch(()=>loading.value');
      if (!val) {
        // 返回媒体id数组
        emit('getMediaList', JSON.parse(JSON.stringify(mediaList.value)))
        mediaList.value = []
      }
    }
  )
  
  </script>
  
  <style lang="less" scoped>
  </style>
  